package com.shouke.jmeter.plugin.elementconfig;

import org.apache.jmeter.config.ConfigElement;
import org.apache.jmeter.config.ConfigTestElement;
import org.apache.jmeter.testbeans.TestBean;

import org.apache.jmeter.testbeans.TestBeanHelper;
import org.apache.jmeter.testelement.TestStateListener;
import org.apache.jmeter.threads.JMeterVariables;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.shouke.RabbitMQ.RabbitMQClient;

public class RabbitMQConnectConfigElement extends ConfigTestElement implements ConfigElement, TestBean, TestStateListener {
    private static final Logger logger = LogManager.getLogger(RabbitMQConnectConfigElement.class);
    private static final long serialVersionUID = 16886449268469L;

    private String rabbitMQConnVariableName;
    private String host;
    private Integer port;
    private String username;
    private String password;
    private Boolean isAutoRecoveryEnabled;
    private Integer networkRecoveryInterval;
    private String virtualHost;
    private Integer connectionTimeout;
    private Integer handshakeTimeout;
    private Integer shutdownTimeout;
    private RabbitMQClient rabbitMQClient;


    /**
     * 主线程开始执行测试之前被调用，注意,不管有多少线程，循环运行多少次，该函数仅会被调用一次
     */
    public void testStarted(){

        // do something you want
        this.setRunningVersion(true);
        TestBeanHelper.prepare(this);

        JMeterVariables variables = getThreadContext().getVariables();

        if (variables.getObject(rabbitMQConnVariableName) != null) {
            logger.error("rabbitMQ is already connected");
        } else {
            synchronized (this) {
                try {
                    this.rabbitMQClient = new RabbitMQClient(getHost(),
                            getPort(),
                            getUsername(),
                            getPassword(),
                            getIsAutoRecoveryEnabled(),
                            getNetworkRecoveryInterval(),
                            getVirtualHost(),
                            getConnectionTimeout(),
                            getHandshakeTimeout(),
                            getShutdownTimeout()
                            );
                    variables.putObject(rabbitMQConnVariableName, rabbitMQClient);
                } catch (Exception e) {
                    logger.error("Error while creating RabbitMQ connection!", e);
                }
            }
        }
    }

    /**
     * 主线程开始执行测试之前被调用
     *
     * @param host
     */
    public void testStarted(String host) {
        logger.info("testStarted, arg: " + host);
        testStarted();
    }

    /**
     * 测试结束后被调用，注意，不管有多少线程，循环运行多少次，该函数仅会被调用一次
     */
    public void testEnded() {
        System.out.print(this.getIsAutoRecoveryEnabled() == true);
        if(this.rabbitMQClient != null){
            try {
                this.rabbitMQClient.close();
            } catch (Exception e) {
                logger.error("Error while closing RabbitMQ client!", e);
            }

            logger.info("RabbitMQ connection terminated");
        }
    }

    /**
     * 测试结束后被调用，注意，不管有多少线程，循环运行多少次，该函数仅会被调用一次
     * @param host
     */
    public void testEnded(String host) {
        logger.debug("testEnded，arg: " + host);
    }

    public String getRabbitMQConnVariableName() {
        return rabbitMQConnVariableName;
    }

    public void setRabbitMQConnVariableName(String rabbitMQConnVariableName) {
        this.rabbitMQConnVariableName = rabbitMQConnVariableName;
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host.trim();
    }

    public Integer getPort() {
        return port;
    }

    public void setPort(Integer port) {
        this.port = port;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username.trim();
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password.trim();
    }

    public Boolean getIsAutoRecoveryEnabled() {
        return isAutoRecoveryEnabled;
    }

    public void setIsAutoRecoveryEnabled(Boolean isAutoRecoveryEnabled) {
        this.isAutoRecoveryEnabled = isAutoRecoveryEnabled;
    }

    public Integer getNetworkRecoveryInterval() {
        return networkRecoveryInterval;
    }

    public void setNetworkRecoveryInterval(Integer networkRecoveryInterval) {
        this.networkRecoveryInterval = networkRecoveryInterval;
    }

    public String  getVirtualHost() {
        return virtualHost;
    }

    public void setVirtualHost(String virtualHost) {
        this.virtualHost = virtualHost;
    }

    public Integer getConnectionTimeout() {
        return connectionTimeout;
    }

    public void setConnectionTimeout(Integer connectionTimeout) {
        this.connectionTimeout = connectionTimeout;
    }

    public Integer getHandshakeTimeout() {
        return handshakeTimeout;
    }

    public void setHandshakeTimeout(Integer handshakeTimeout) {
        this.handshakeTimeout = handshakeTimeout;
    }


    public Integer getShutdownTimeout() {
        return shutdownTimeout;
    }

    public void setShutdownTimeout(Integer shutdownTimeout) {
        this.shutdownTimeout = shutdownTimeout;
    }

}

